package com.kunter.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;

import cn.kunter.common.log.Log;

/**
 * Mybatis 配置
 * @author yangziran
 * @version 1.0 2015年12月29日
 */
@Configuration
@EnableTransactionManagement
@ConditionalOnClass({ EnableTransactionManagement.class })
@MapperScan(basePackages = { "com.kunter.admin.dao" })
public class MybatisConfiguration implements EnvironmentAware {

    private RelaxedPropertyResolver propertyResolver;

    @Override
    public void setEnvironment(Environment environment) {

        this.propertyResolver = new RelaxedPropertyResolver(environment, environment.getActiveProfiles()[0] + ".jdbc.");
    }

    @Bean(destroyMethod = "close", initMethod = "init")
    public DataSource dataSource() {

        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(propertyResolver.getProperty("url"));
        datasource.setDriverClassName(propertyResolver.getProperty("driverClassName"));
        datasource.setUsername(propertyResolver.getProperty("username"));
        datasource.setPassword(propertyResolver.getProperty("password"));

        datasource.setInitialSize(1);
        datasource.setMinIdle(1);
        datasource.setMaxActive(5);
        datasource.setMaxWait(60000);

        datasource.setTimeBetweenEvictionRunsMillis(60000);
        datasource.setMinEvictableIdleTimeMillis(300000);

        datasource.setValidationQuery("select 1");
        datasource.setTestWhileIdle(true);
        datasource.setTestOnBorrow(false);
        datasource.setTestOnReturn(false);

        datasource.setPoolPreparedStatements(false);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(20);

        try {
            datasource.setFilters("stat");
        } catch (SQLException e) {
            Log.error(MybatisConfiguration.class, "dataSource", e);
        }

        return datasource;
    }

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory() {

        try {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));

            return sessionFactory.getObject();
        } catch (Exception e) {
            Log.error(MybatisConfiguration.class, "sqlSessionFactory", e);
            return null;
        }
    }

    @Bean
    @ConditionalOnMissingBean
    public DataSourceTransactionManager transactionManager() {

        return new DataSourceTransactionManager(dataSource());
    }
}
